<template>
  <el-dialog
    title="选择地点"
    width="740px"
    class="select-map-dialog"
    v-model="dialogShow"
    align-center
    :close-on-click-modal="false"
    :modal-orgend-to-body="false"
    :append-to-body="true"
    @close="cancel"
  >
    <div class="amap-box">
      <el-input
        clearable
        id="keyword"
        v-model="tipInput"
        placeholder="关键词搜索"
        :prefix-icon="Search"
      ></el-input>
      <div id="custom-amap"></div>
      <div class="info-list mt10" v-if="point.length">
        <div class="info-item">已选择地点：{{ address }}</div>
        <div class="info-item">地点经纬度：{{ point }}</div>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="handelSave">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, onUnmounted, watch, computed, nextTick } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";

const { proxy } = getCurrentInstance();
const map = ref(null); // 地图对象
const address = ref(""); // 地址
const point = ref([]); // 地址对应的经纬度信息

const marker = ref(""); // 地图标记
const geocoder = ref(""); // 地址解析（正向）

const tipInput = ref(""); // 检索关键字
const autoComplete = ref(null);
const placeSearch = ref(null);

const props = defineProps({
  defaultAddress: {
    type: String,
    default: "",
  },
  defaultPoint: {
    type: Array,
  },
  isShow: {
    type: Boolean,
    default: false,
  },
});

const emits = defineEmits(["update:isShow", "getPosition"]);
const dialogShow = computed({
  get: () => props.isShow,
  set: (value) => {
    emits("update:isShow", value);
    address.value = "";
    point.value = [];
    tipInput.value = "";
  },
});
watch(
  () => dialogShow,
  async () => {
    await nextTick();
    // 初始化地图页面
    initMap();
  },
  { deep: true },
  { immediate: true }
);

//   初始化地图页面
const initMap = () => {
  AMapLoader.load({
    key: "a11b92595e91e2c356d8d1fd93e30290", // 申请好的Web端开发者Key，首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    plugins: [
      "AMap.GeoJSON",
      "AMap.MarkerClusterer",
      "AMap.MouseTool",
      "AMap.Geocoder",
      "AMap.PlaceSearch",
      "AMap.AutoComplete",
    ], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
  })
    .then((AMap) => {
      map.value = new AMap.Map("custom-amap", {
        // 设置地图容器id
        viewMode: "2D", // 是否为3D地图模式
        zoom: 12, // 初始化地图级别
        showLabel: true, // 是否展示地图文字和 POI 信息。
        resizeEnable: true,
        // center: tempCenter, // 初始化地图中心点位置
      });
      // 如果父组件传入了有效值 回显一个icon
      if (props.defaultPoint.length) {
        address.value = props.defaultAddress;
        point.value = props.defaultPoint;
        addMarker();
      }
      tipInput.value = props.defaultAddress;
      if (tipInput.value) {
        getGeoCode();
      }
      // 地图点击事件
      map.value.on("click", clickMapHandler);

      // 搜索框自动完成类
      autoComplete.value = new AMap.AutoComplete({
        input: "keyword", // input 为绑定输入提示功能的input的DOM ID
      });
      // 构造地点查询类
      placeSearch.value = new AMap.PlaceSearch({
        map: map.value,
      });
      // 当选中某条搜索记录时触发
      autoComplete.value.on("select", selectHandler);
      // poi覆盖物点击事件
      placeSearch.value.on("markerClick", clickMarkerHandler);
    })
    .catch((e) => {});
};

const clickMapHandler = (e) => {
  point.value = [e.lnglat.lng, e.lnglat.lat];
  // 增加点标记
  addMarker();
  // 获取地址
  getAddress();
};

// 增加点标记
const addMarker = () => {
  // 清除其他icon
  if (marker.value) {
    marker.value.setMap(null);
    marker.value = null;
  }
  // 重新渲染icon
  marker.value = new AMap.Marker({
    position: point.value, // icon经纬度
    offset: new AMap.Pixel(-13, -30), // icon中心点的偏移量
    icon: new AMap.Icon({
      image:
        "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
      size: new AMap.Size(30, 40), // 图标大小
      imageSize: new AMap.Size(30, 40),
    }),
  });
  marker.value.setMap(map.value); // 设置icon
};

// 将经纬度转换为地址
const getAddress = () => {
  // 获取地址,这里通过高德 SDK 完成。
  geocoder.value = new AMap.Geocoder();
  // 调用逆解析方法, 个人开发者调用量上限5000（次/日）
  geocoder.value.getAddress(point.value, (status, result) => {
    if (status === "complete" && result.info === "OK") {
      if (result && result.regeocode) {
        address.value = result.regeocode.formattedAddress;
      }
    }
  });
};
// 将地址转换为经纬度
const getGeoCode = () => {
  // 获取地址,这里通过高德 SDK 完成。
  geocoder.value = new AMap.Geocoder();
  // 调用逆解析方法, 个人开发者调用量上限5000（次/日）
  geocoder.value.getLocation(tipInput.value, (status, result) => {
    if (status === "complete" && result.geocodes.length) {
      point.value = [
        result.geocodes[0].location.lng,
        result.geocodes[0].location.lat,
      ];
      address.value = tipInput.value;
      addMarker();
    } else {
      proxy.$modal.msgError(`根据地址查询位置失败，请重新输入检索！`);
    }
  });
};
// 当选中某条记录时会触发
const selectHandler = (e) => {
  placeSearch.value.setCity(e.poi.adcode);
  placeSearch.value.search(e.poi.name); // 关键字查询查询
};
// 点击poi覆盖物事件
const clickMarkerHandler = (e) => {
  point.value = [e.data.location.lng, e.data.location.lat];
  getAddress();
};

// 保存当前选择的地址,分发事件
const handelSave = () => {
  if (point.value.length) {
    tipInput.value = "";
    emits("getPosition", point.value, address.value);
  } else {
    proxy.$modal.msgWarning("请选择地址获取经纬度");
  }
};
const cancel = () => {
  tipInput.value = "";
  emits("getPosition", []);
};

onUnmounted(() => {
  map.value && map.value.destroy();
  address.value = "";
  point.value = [];
  tipInput.value = "";
});
</script>

<style lang="scss" scoped>
.amap-box {
  padding: 5px 0 0;
  #custom-amap {
    width: 100%;
    height: 400px;
    margin-top: 10px;
    border: 1px solid #ccc;
  }

  .input-with {
    width: 580px;
    z-index: 1;
  }

  .address {
    color: #373737;
  }
  .info-list {
    padding: 5px 5px 0;
    line-height: 24px;
  }
}
</style>

<style lang="scss">
.select-map-dialog {
  .el-dialog__body {
    padding-top: 3px;
    padding-bottom: 3px;
  }
}
.amap-sug-result {
  z-index: 2024;
}
</style>
